{
    // 从 类型 中 排除 键
    type type_test = {
        a: string;
        b: string;
    };

    type Omit_a = Omit<type_test, 'a'>;
    type Omit_b = Omit<type_test, 'b'>;
    type Omit_ab = Omit<type_test, 'a' | 'b'>;
}

{
    // 从 类型 中 排除 类型
    type type_test = Exclude<string | number, string>;
    let a: type_test;
    a = 0;
    // Type 'string' is not assignable to type 'number'.ts(2322)
    a = '';

    let fn = <T>(arg: Exclude<T, string>) => { };
    fn(0)
    fn({})
    fn([])
    fn(true)
    // Argument of type 'string' is not assignable to parameter of type 'never'.ts(2345)
    fn('')

    type type_test2 = Exclude<0 | 1 | 2, 1>;
    let b: type_test2;
    b = 0;
    // Type '1' is not assignable to type 'type_test2'.ts(2322)
    b = 1;
    b = 2;
}

{
    // 数组长度的联合类型
    const arr = ['x', 'y', 'z'] as const;
    type type_test = TarrayIndexs<typeof arr['length']>;
    let a: type_test;
    // Type '"0"' is not assignable to type '0 | 1 | 2'.ts(2322)
    a = '0';
    a = 0;
    a = 1;
    a = 2;
    // Type '3' is not assignable to type '0 | 1 | 2'.ts(2322)
    a = 3;
}

{
    {// 当类的长相一致时，ts会将它们看做是同一类型。
        // InstanceType<typeof AAA> 与 AAA 表现一致
        class AAA { }
        class BBB { }

        let a: InstanceType<typeof AAA>;
        a = new AAA();
        a = new BBB();

        let b: AAA;
        b = new AAA();
        b = new BBB();
    }
    {// 当类的长相一致时，ts会将它们看做是同一类型。
        // InstanceType<typeof AAA> 与 AAA 表现一致
        class AAA { x = 1; }
        class BBB { x = 2; }

        let a: InstanceType<typeof AAA>;
        a = new AAA();
        a = new BBB();

        let b: AAA;
        b = new AAA();
        b = new BBB();
    }
    {// 当类的长相不一致时，ts才会将它们看做是不同类型。
        // InstanceType<typeof AAA> 与 AAA 表现一致
        class AAA { x = 1; }
        class BBB { x = '1'; }

        let a: InstanceType<typeof AAA>;
        a = new AAA();
        // Type 'string' is not assignable to type 'number'.ts(2322)
        a = new BBB();

        let b: AAA;
        b = new AAA();
        // Type 'string' is not assignable to type 'number'.ts(2322)
        b = new BBB();
    }
    {// 当类的长相不一致时，ts才会将它们看做是不同类型。
        // InstanceType<typeof AAA> 与 AAA 表现一致
        class AAA { x = 1; }
        class BBB { y = 1; }

        let a: InstanceType<typeof AAA>;
        a = new AAA();
        // Property 'x' is missing in type 'BBB' but required in type 'AAA'.ts(2741)
        a = new BBB();

        let b: AAA;
        b = new AAA();
        // Property 'x' is missing in type 'BBB' but required in type 'AAA'.ts(2741)
        b = new BBB();
    }
    {// 子类对象可以给父类类型
        // InstanceType<typeof AAA> 与 AAA 表现一致
        class AAA { x = 1; }
        class BBB extends AAA { y = '1'; }

        let a: InstanceType<typeof AAA>;
        a = new AAA();
        a = new BBB();

        let b: AAA;
        b = new AAA();
        b = new BBB();
    }
    {// 子类可以给抽象父类类型
        // InstanceType<typeof AAA> 与 AAA 表现一致
        abstract class AAA { x = 1; }
        class BBB extends AAA { y = '1'; }

        let a: InstanceType<typeof AAA>;
        a = new BBB();

        let b: AAA;
        b = new BBB();
    }
    {// InstanceType<typeof AAA> 与 AAA 区别
        interface AAA { }
        class BBB implements AAA { }

        // InstanceType 不能使用接口
        // 'AAA' only refers to a type, but is being used as a value here.ts(2693)
        let a: InstanceType<typeof AAA>;
        a = new BBB();

        let b: AAA;
        b = new BBB();
    }
    {// 从 U1 中 排除掉 U2
        type U1 = 'a' | 'b' | 'c' | 'd';
        type U2 = 'a' | 'b';
        type r = TExcludeUnion<U1, U2>;
    }
    {// 枚举键
        enum X {
            innerText = 'innerText',
            innerHTML = 'innerHTML',
            textContent = 'textContent',
        };

        type x = EnumKeys<typeof X>;
    }
}
